package com.artisan.springuitls.demos;

import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.List;

/**
 * LinkedMultiValueMap 工具类演示
 * 功能：多值 Map 实现
 * 优势：一个 key 对应多个 value，且保留插入顺序
 */
@Component
public class LinkedMultiValueMapDemo {

    /**
     * 场景：处理 HTTP 表单参数
     */
    public void processForm() {
        System.out.println("\n========== LinkedMultiValueMap Demo ==========");
        
        // ✅ 创建多值 Map
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        
        // 添加重复 key
        params.add("hobby", "篮球");
        params.add("hobby", "足球");
        params.add("hobby", "游泳");
        params.add("name", "张三");
        params.add("age", "25");
        
        // ✅ 获取 List
        System.out.println("✓ 爱好列表: " + params.get("hobby")); // [篮球, 足球, 游泳]
        System.out.println("✓ 姓名: " + params.getFirst("name")); // 张三
        
        // ✅ 遍历所有值
        System.out.println("✓ 所有参数:");
        params.forEach((key, values) -> 
            System.out.println("  - " + key + " = " + values)
        );
    }

    /**
     * 演示基础操作
     */
    public void demonstrateBasicOperations() {
        System.out.println("\n--- 基础操作 ---");
        
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        
        // 1. add() - 添加值到列表
        map.add("tags", "java");
        map.add("tags", "spring");
        map.add("tags", "boot");
        System.out.println("✓ add() 后 tags: " + map.get("tags"));
        
        // 2. set() - 替换整个列表
        map.set("tags", "python");
        System.out.println("✓ set() 后 tags: " + map.get("tags"));
        
        // 3. addAll() - 批量添加
        map.addAll("tags", List.of("django", "flask"));
        System.out.println("✓ addAll() 后 tags: " + map.get("tags"));
        
        // 4. getFirst() - 获取第一个值
        System.out.println("✓ getFirst('tags'): " + map.getFirst("tags"));
        
        // 5. remove() - 删除键
        map.remove("tags");
        System.out.println("✓ remove() 后 tags: " + map.get("tags"));
        
        System.out.println();
    }

    /**
     * 演示 HTTP 请求参数场景
     */
    public void demonstrateHttpParameters() {
        System.out.println("\n--- HTTP 请求参数场景 ---");
        
        // 模拟 HTTP 请求：/search?category=电子&category=家电&price=100&price=500
        MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
        
        queryParams.add("category", "电子");
        queryParams.add("category", "家电");
        queryParams.add("price", "100");
        queryParams.add("price", "500");
        queryParams.add("sort", "price_asc");
        
        System.out.println("✓ 查询参数:");
        System.out.println("  - 分类: " + queryParams.get("category"));
        System.out.println("  - 价格范围: " + queryParams.get("price"));
        System.out.println("  - 排序: " + queryParams.getFirst("sort"));
        
        // 处理多选参数
        List<String> categories = queryParams.get("category");
        if (categories != null) {
            System.out.println("✓ 选中的分类:");
            categories.forEach(cat -> System.out.println("  - " + cat));
        }
        
        System.out.println();
    }

    /**
     * 演示 HTTP 表单提交
     */
    public void demonstrateFormSubmission() {
        System.out.println("\n--- HTTP 表单提交场景 ---");
        
        // 模拟表单数据
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
        
        formData.add("username", "zhangsan");
        formData.add("email", "zhangsan@example.com");
        formData.add("interests", "编程");
        formData.add("interests", "阅读");
        formData.add("interests", "旅游");
        formData.add("subscribe", "true");
        
        System.out.println("✓ 表单数据:");
        System.out.println("  - 用户名: " + formData.getFirst("username"));
        System.out.println("  - 邮箱: " + formData.getFirst("email"));
        System.out.println("  - 兴趣: " + formData.get("interests"));
        System.out.println("  - 订阅: " + formData.getFirst("subscribe"));
        
        // 转换为 Spring MVC 可用的格式
        System.out.println("✓ 在 Spring MVC 中使用:");
        System.out.println("  @PostMapping(\"/register\")");
        System.out.println("  public String register(@RequestParam MultiValueMap<String, String> formData) {");
        System.out.println("      List<String> interests = formData.get(\"interests\");");
        System.out.println("      // 处理表单数据");
        System.out.println("  }");
        
        System.out.println();
    }

    /**
     * 演示 HTTP 请求头
     */
    public void demonstrateHttpHeaders() {
        System.out.println("\n--- HTTP 请求头场景 ---");
        
        // 模拟 HTTP 请求头（可以有多个相同名称的头）
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        
        headers.add("Accept", "text/html");
        headers.add("Accept", "application/json");
        headers.add("Accept-Language", "zh-CN");
        headers.add("Accept-Language", "en-US");
        headers.add("User-Agent", "Mozilla/5.0");
        
        System.out.println("✓ 请求头:");
        headers.forEach((name, values) -> 
            System.out.println("  - " + name + ": " + String.join(", ", values))
        );
        
        // Spring Web 使用
        System.out.println("\n✓ Spring Web 中:");
        System.out.println("  - HttpHeaders 就是 MultiValueMap<String, String>");
        System.out.println("  - @RequestHeader MultiValueMap<String, String> headers");
        
        System.out.println();
    }

    /**
     * 演示与 RestTemplate 集成
     */
    public void demonstrateRestTemplateUsage() {
        System.out.println("\n--- RestTemplate 使用场景 ---");
        
        // POST 请求体
        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("username", "admin");
        requestBody.add("password", "123456");
        
        System.out.println("✓ POST 请求示例:");
        System.out.println("  MultiValueMap<String, String> body = new LinkedMultiValueMap<>();");
        System.out.println("  body.add(\"username\", \"admin\");");
        System.out.println("  body.add(\"password\", \"123456\");");
        System.out.println("  ");
        System.out.println("  HttpHeaders headers = new HttpHeaders();");
        System.out.println("  headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);");
        System.out.println("  ");
        System.out.println("  HttpEntity<MultiValueMap<String, String>> request = ");
        System.out.println("      new HttpEntity<>(body, headers);");
        System.out.println("  ");
        System.out.println("  ResponseEntity<String> response = ");
        System.out.println("      restTemplate.postForEntity(url, request, String.class);");
        
        System.out.println();
    }

    /**
     * 演示数据转换
     */
    public void demonstrateDataConversion() {
        System.out.println("\n--- 数据转换 ---");
        
        MultiValueMap<String, String> multiMap = new LinkedMultiValueMap<>();
        multiMap.add("key1", "value1");
        multiMap.add("key1", "value2");
        multiMap.add("key2", "value3");
        
        // 1. 转为单值 Map（取第一个值）
        System.out.println("✓ 转为单值 Map:");
        multiMap.toSingleValueMap().forEach((key, value) -> 
            System.out.println("  - " + key + " = " + value)
        );
        
        // 2. 获取所有 key
        System.out.println("✓ 所有 key: " + multiMap.keySet());
        
        // 3. 获取所有 value 列表
        System.out.println("✓ 所有 value 列表: " + multiMap.values());
        
        // 4. 检查是否为空
        System.out.println("✓ 是否为空: " + multiMap.isEmpty());
        
        // 5. 大小
        System.out.println("✓ 大小: " + multiMap.size());
        
        System.out.println();
    }

    /**
     * 实际应用：文件上传
     */
    public void demonstrateFileUpload() {
        System.out.println("\n--- 文件上传场景 ---");
        
        System.out.println("✓ Spring MVC 文件上传:");
        System.out.println("  @PostMapping(\"/upload\")");
        System.out.println("  public String upload(");
        System.out.println("      @RequestParam(\"files\") List<MultipartFile> files,");
        System.out.println("      @RequestParam MultiValueMap<String, String> params) {");
        System.out.println("      ");
        System.out.println("      String description = params.getFirst(\"description\");");
        System.out.println("      List<String> tags = params.get(\"tags\");");
        System.out.println("      ");
        System.out.println("      // 处理文件和参数");
        System.out.println("      return \"success\";");
        System.out.println("  }");
        
        System.out.println();
    }

    /**
     * 与普通 Map 对比
     */
    public void compareWithNormalMap() {
        System.out.println("\n--- 与普通 Map 对比 ---");
        
        System.out.println("✓ Map<String, List<String>>:");
        System.out.println("  - 需要手动创建 List");
        System.out.println("  - 需要判空处理");
        System.out.println("  - 代码冗长");
        System.out.println("");
        System.out.println("✓ MultiValueMap<String, String>:");
        System.out.println("  - 自动管理 List");
        System.out.println("  - 提供 add/set/getFirst 方法");
        System.out.println("  - 代码简洁");
        System.out.println("");
        System.out.println("✓ 示例对比:");
        System.out.println("  // 普通 Map");
        System.out.println("  Map<String, List<String>> map = new HashMap<>();");
        System.out.println("  List<String> list = map.get(\"key\");");
        System.out.println("  if (list == null) {");
        System.out.println("      list = new ArrayList<>();");
        System.out.println("      map.put(\"key\", list);");
        System.out.println("  }");
        System.out.println("  list.add(\"value\");");
        System.out.println("");
        System.out.println("  // MultiValueMap");
        System.out.println("  MultiValueMap<String, String> multiMap = new LinkedMultiValueMap<>();");
        System.out.println("  multiMap.add(\"key\", \"value\");");
        
        System.out.println("==========================================\n");
    }

    /**
     * 最佳实践
     */
    public void printBestPractices() {
        System.out.println("\n========== 最佳实践 ==========");
        System.out.println("✓ 1. 处理 HTTP 请求参数时使用");
        System.out.println("✓ 2. 处理表单提交时使用");
        System.out.println("✓ 3. RestTemplate POST 请求体");
        System.out.println("✓ 4. 使用 add() 添加多个值");
        System.out.println("✓ 5. 使用 set() 替换所有值");
        System.out.println("✓ 6. 使用 getFirst() 获取单个值");
        System.out.println("✓ 7. Spring MVC 自动支持此类型");
        System.out.println("✓ 8. 比 Map<String, List<String>> 更简洁");
        System.out.println("==========================================\n");
    }
}

